<template>
    <el-drawer v-model="visible" title="OCR识别" size="100%" :close-on-click-modal="false">
        <div class="ocr-drawer-content">
            <!-- 左右布局 -->
            <div class="ocr-main-layout">
                <!-- 左侧：图片上传和预览 -->
                <div class="ocr-left-panel">
                    <!-- 图片预览区 -->
                    <div v-if="imgUrl" class="ocr-img-preview">
                        <img :src="imgUrl" alt="预览" />
                    </div>
                    <!-- 上传区 -->
                    <div class="ocr-upload-box">
                        <el-upload class="upload-demo" action="" :show-file-list="false" :auto-upload="false"
                            :before-upload="handleBeforeUpload" :on-change="handleFileChange" :file-list="fileList"
                            accept="image/*">
                            <el-button type="primary">选择图片</el-button>
                        </el-upload>
                    </div>
                </div>

                <!-- 右侧：识别结果 -->
                <div class="ocr-right-panel">
                    <!-- Text结果 -->
                    <div class="ocr-result-item">
                        <div class="result-label">识别文本：</div>
                        <el-input type="textarea" :rows="12" v-model="serializedOcrText" placeholder="识别的文本内容将在此显示"
                            readonly />
                    </div>

                    <!-- Data结果 -->
                    <div class="ocr-result-item">
                        <div class="result-label">有效数据：</div>
                        <el-input type="textarea" :rows="12" v-model="serializedOcrData" placeholder="接口返回的原始数据将在此显示"
                            readonly />
                    </div>
                </div>
            </div>
        </div>

        <!-- 底部按钮区 -->
        <template #footer>
            <div class="ocr-footer">
                <span v-if="taskEmpty" style="color: #909399;" class="time-ms">当前无任务</span>
                <span v-else style="color: #67C23A;" class="time-ms">正在处理{{ taskList.length }}个任务</span>
                <span class="time-ms">|</span>
                <span class="time-ms">图片优化：{{ optimizeTime }} ms</span>
                <span class="time-ms">|</span>
                <span class="time-ms">OCR识别：{{ ocrTime }} ms</span>
                <span class="time-ms">|</span>
                <span class="time-ms">LLM处理：{{ chatTime }} ms</span>
                <span class="time-ms">|</span>
                <span class="time-ms">总耗时：{{ endTime - startTime > 0 ? endTime - startTime : 0 }} ms</span>
                <el-button type="success" :loading="loading" @click="handleSubmit" :disabled="!file">OCR+LLM</el-button>
            </div>
        </template>
    </el-drawer>
</template>

<script setup>
import { ref } from "vue";
import { ElMessage } from "element-plus";
import axios from "axios";
import { listMyKey } from "@/api/system/key";

const keyList = ref([])
const visible = ref(false);
const file = ref(null);
const fileList = ref([]);
const ocrText = ref([]);
const ocrData = ref([]);
const loading = ref(false);
const imgUrl = ref("");
const optimizeTime = ref(0);
const ocrTime = ref(0);
const chatTime = ref(0);
const startTime = ref(0);
const endTime = ref(0);

const taskList = ref([]);
const isQuerying = ref(false);

function getMyApiKey() {
    listMyKey().then(response => {
        keyList.value = response.rows
    })
}

function handleBeforeUpload() {
    return false;
}

function handleFileChange(fileObj) {
    file.value = fileObj.raw;
    fileList.value = [fileObj];
    imgUrl.value = URL.createObjectURL(fileObj.raw);
}

const serializedOcrText = computed(() => ocrText.value.join(" "));
const serializedOcrData = computed(() => JSON.stringify(ocrData.value));
const taskEmpty = computed(() => taskList.value.length === 0);

async function handleSubmit() {
    if (!file.value) return;
    loading.value = true;
    if (!startTime.value) startTime.value = (new Date()).getTime()
    try {
        const formData = new FormData();
        formData.append("file", file.value);
        const res = await axios.post("/api/ocr/llm/binary-task?scenario=material_label", formData, {
            headers: { "Content-Type": "multipart/form-data", "Ocr-Api-Key": keyList.value[0].apiKey || "" },
        });
        if (res.data && res.data.data) {
            taskList.value.push(res.data.data.task_id);
            ElMessage.success("任务创建成功");
        } else {
            ElMessage.error(res.data.msg || "任务创建失败");
        }
    } catch (e) {
        ElMessage.error("任务创建失败");
    }
    loading.value = false;
}

const open = () => {
    visible.value = true;
    file.value = null;
    fileList.value = [];
    ocrText.value = [];
    ocrData.value = [];
    imgUrl.value = "";
    optimizeTime.value = 0;
    ocrTime.value = 0;
    chatTime.value = 0;
    getMyApiKey();
    setInterval(async () => {
        if (taskList.value.length > 0 && !isQuerying.value) {
            isQuerying.value = true;
            const waitRemoveTasks = [];
            for (const taskId of taskList.value) {
                const res = await axios.get(`/api/ocr/llm/task/${taskId}`, {
                    headers: { "Ocr-Api-Key": keyList.value[0].apiKey || "" },
                });
                const task = res.data.data || [];
                if (task.status === "completed") {
                    waitRemoveTasks.push(task.task_id);
                    ocrText.value.push(...(res.data.data.texts || []));
                    ocrData.value.push(...(res.data.data.data || []));
                    optimizeTime.value += res.data.data.img_ms || 0;
                    ocrTime.value += res.data.data.ocr_ms || 0;
                    chatTime.value += res.data.data.llm_ms || 0;
                    ElMessage.success(`任务 ${task.task_id} 识别成功`);
                } else if (task.status === "failed") {
                    waitRemoveTasks.push(task.task_id);
                    ElMessage.error(`任务 ${task.task_id} 识别失败`);
                }
            }
            waitRemoveTasks.forEach((taskId) => {
                const index = taskList.value.indexOf(taskId);
                if (index !== -1) taskList.value.splice(index, 1);
            });
            if (taskList.value.length === 0) {
                endTime.value = (new Date()).getTime()
            }
            isQuerying.value = false;
        }
    }, 3000)
};

defineExpose({
    open,
});
</script>

<style scoped>
.ocr-drawer-content {
    height: calc(100% - 60px);
    display: flex;
    flex-direction: column;
}

.ocr-main-layout {
    display: flex;
    gap: 20px;
    height: 100%;
}

.ocr-left-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.ocr-right-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.ocr-upload-box {
    text-align: center;
    padding: 16px;
    border: 2px dashed #dcdfe6;
    border-radius: 6px;
    background-color: #fafafa;
}

.ocr-img-preview {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #eee;
    border-radius: 6px;
    background-color: #f9f9f9;
    overflow: hidden;
}

.ocr-img-preview img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: 6px;
}

.ocr-result-item {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.result-label {
    font-weight: 500;
    margin-bottom: 8px;
    color: #303133;
}

.ocr-footer {
    text-align: right;
    padding: 8px 0;
}

.time-ms {
    font-size: 12px;
    margin-right: 16px;
    color: #909399;
}

/* 响应式设计 */
@media (max-width: 768px) {
    .ocr-main-layout {
        flex-direction: column;
    }

    .ocr-left-panel {
        flex: none;
    }

    .ocr-img-preview {
        height: 200px;
    }
}
</style>